home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Storage / LinkSrc.cpp < prev    next >
Encoding:
Text File  |  1996-04-22  |  27.0 KB  |  838 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        LinkSrc.cpp
  3.  
  4.     Contains:    Implementation of ODLinkSource class
  5.  
  6.     Owned by:    Craig Carper
  7.  
  8.     Copyright:    © 1993 - 1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <41>     10/8/95    TJ        Fixes Recomended by Refball
  13.         <40>     10/4/95    jpa        Added missing ODVolatiles [1285799]
  14.         <39>     10/3/95    TJ        Added Includes so it compiles
  15.         <38>     10/3/95    TJ        Changes done by RefBall Team
  16.         <37>      9/8/95    TÇ        1281096 FB2:Many constants in ODTypesB
  17.                                     without kOD prefix!
  18.         <36>      9/1/95    CC        1278590: Added SetStatus(ODError error).
  19.         <35>     8/12/95    TÇ        1276807 Opt./Bug: use StdTypIO routines for
  20.                                     portable streaming & smaller footprint
  21.         <34>      8/3/95    RR        #1257260: Collapse B classes. Remove
  22.                                     somInit methods. Don't call IsInitialized
  23.                                     or SubclassResponsibility
  24.         <33>     7/28/95    CC        1183569: Externalize only when dirty.
  25.         <32>     7/20/95    CC        1225443: ShowSourceContent: If the section
  26.                                     isn't registered, register temporarily to
  27.                                     call GetEditionInfo.
  28.         <31>     6/12/95    CC        1248090: CloneFromMemoryContainer: Force
  29.                                     cloning of frame referenced by
  30.                                     kODPropContentFrame property.
  31.         <30>     5/26/95    VL        1251403: Multithreading naming support.
  32.         <29>     5/25/95    jpa        Fixed usage of ODDebug. [1253321]
  33.         <28>     5/18/95    CC        1238898: Add destFrame argument to
  34.                                     BeginClone call.
  35.         <27>     4/27/95    CC        1242555: Removed $5 checkin comment (doh!)
  36.         <26>     4/14/95    TÇ        #1235279 BB: InfoUtil & StdTypIO functions
  37.                                     should take Environment* and SU* when
  38.                                     possible
  39.         <25>     4/11/95    CC        1236452: Added SOM_CATCH to InitLinkSource
  40.                                     and Release.
  41.         <24>      3/3/95    CC        1210760 SetAutoUpdate: update edition file
  42.                                     on change to manual from automatic update.
  43.                                     1223861 Added GetStatus(); maintain fStatus
  44.                                     field.
  45.         <23>      2/7/95    CC        1217192: ReadLinkEdition must call
  46.                                     somSelf->SetChangeTime AFTER closing the
  47.                                     edition file.
  48.         <22>     1/19/95    CC        1210953 Added override of SetSourcePart.
  49.                                     1193561 Code review changes.
  50.         <21>    12/22/94    CC        1153759 UseLinkEdition - call ODDRaft::
  51.                                     SetChangedFromPrev().
  52.         <20>    12/20/94    VL        1195012: Make Storage calls be
  53.                                     marshallable.
  54.         <19>    12/16/94    CC        1203516 Removed ODLink parameter from
  55.                                     InitLinkSource().
  56.         <18>     12/8/94    CC        1154711 Use ">= kODSharedWrite" to check
  57.                                     for write access.
  58.         <17>    10/10/94    CC        1160355 - Don't register with Edition mgr.
  59.                                     if draft is read only.
  60.         <16>     10/7/94    CC        1191089 - Cross-document updates get new
  61.                                     unique ID.
  62.         <15>     10/4/94    CC        1190862 - Added override of Release().
  63.         <14>     9/29/94    RA        1189812: Mods for 68K build.
  64.         <13>     9/23/94    VL        1184272: ContainerID is now a sequence of
  65.                                     octets.
  66.         <12>     9/15/94    CC        1186669 - Implemented CloneInto().
  67.         <11>      9/7/94    CC        #1185114 - Catch throws from KeyValid().
  68.         <10>     8/26/94    VL        1183174: Use updated cloning APIs.
  69.          <9>     8/15/94    TÇ        #1180922 Removed most obsolete types from
  70.                                     StdTypes.idl
  71.          <8>     8/10/94    CC        1179943 - Moved platform-independent
  72.                                     implementation into LinkSrcB.cpp.
  73.          <7>      8/5/94    CC        #1179160 - ContentUpdated() takes ODLinkKey
  74.                                     parameter and sets fContentUpdated instead
  75.                                     of updating dependents immediately;
  76.                                         Unlock() updates dependents if contents
  77.                                     have changed while locked;
  78.                                         #1153789 (partial implementation) -
  79.                                     Clear() iterates over values in contents
  80.                                     property and deletes all data;
  81.          <6>      8/3/94    VL        1153123: Storage to ODStor.
  82.          <5>     6/24/94    CC        Clean up some easy $5.
  83.          <4>     6/24/94    CC        Added call to ShowLinkSourceInfo().
  84.          <3>     6/24/94    CC        Changed parameters to InitBaseLinkSource().
  85.          <2>     6/21/94    CC        Temporarily remove #include of LinkDlgs.h.
  86.          <1>     6/21/94    CC        first checked in
  87.  
  88.         ------------------- CC ---- Converted to SOM
  89.  
  90.          <6>      5/9/94    MB        #1162181: Changes necessary to install MMM.
  91.          <5>      4/7/94    CC        SetSourcePart: Allow source part to be nil;
  92.                                     Externalize: Remove source part property
  93.                                     source part is nil.  (1154858)
  94.          <4>      4/4/94    CC        CloneFromMemoryContainer: Changed
  95.                                     SetValue() to GetValue() to read
  96.                                     modification date. (1154449)
  97.          <3>     3/28/94    CG        1153547: XMPSessn.h renamed to XMPSessM.h
  98.          <2>     3/27/94    TÇ        #1153523.  Adjust name of
  99.                                     kXMPPropRootPartSU to more clearly indicate
  100.                                     what it is supposed to be used for.
  101.          <1>     3/25/94    CC        first checked in
  102.  
  103.         ------------------- CC ---- Moved from Core to Storage subsystem
  104.  
  105.          <5>     3/24/94    CC        Implemented CloneTo() (1153038) and
  106.                                     GetChangeTime() (115340); renamed
  107.                                     SetAutoExport() and IsAutoExport() to
  108.                                     SetAutoUpdate() and IsAutoUpdate()
  109.                                     (1142938).
  110.          <4>     3/14/94    CC        Added SetSourcePart(). (1149440)
  111.          <3>      3/1/94    JA        Include ODMemory.h (1147588)
  112.          <2>      3/1/94    CC        Replaced calls to HLock, HUnlock, and
  113.                                     GetHandleSize with XMP equivalents.
  114.          <9>      2/8/94    TÇ        Throw -> THROW & some code clean up
  115.          <8>      2/7/94    TÇ        more fixes to compile with PPC Headers
  116.          <7>      2/4/94    TÇ        fixes to compile with PPC Universal headers
  117.          <6>      2/3/94    CG        System Session break out.
  118.          <5>      2/1/94    CC        Pass ODCloneKind argument to BeginClone.
  119.          <4>     1/28/94    CC        Added ReleaseAll(); InitLinkSource does not
  120.                                     increment ref count of argument link
  121.                                     object.
  122.          <3>     1/27/94    VL        Used ODStorageUnit::CloneInto.
  123.          <2>     1/22/94    CC        Don't call release() in destructor.
  124.          <1>     1/21/94    CC        first checked in
  125.         <17>     1/18/94    CG        Added include for StorgDef.h
  126.         <16>     1/18/94    CC        Use kXMPScrapTypePart; release draft
  127.                                     properties on failure in
  128.                                     CloneToMemoryContainer and
  129.                                     CloneFromMemoryContainer
  130.         <15>     1/14/94    CC        Added Lock(), Unlock(), GetTimeStamp(),
  131.                                     GetStatus(), SetAutoExport(),
  132.                                     IsAutoExport(), Export(),
  133.                                     ShowSourceContent(), type ODLinkKey; added
  134.                                     key parameter to various routines; renamed
  135.                                     Edition Manager support routines.
  136.         <14>     1/11/94    TÇ        Init... changes
  137.         <13>    12/22/93    CC        Maintain persistent fields fContentSU and
  138.                                     fChangedDate.  Read/write link content
  139.                                     from/to edition file by cloning fContentSU
  140.                                     into a memory container.  Increment link
  141.                                     ref count for registered sections.  Write
  142.                                     edition files only on Externalize().
  143.         <12>    12/21/93    VL        Changed ODStorageUnit::GetValueSize to
  144.                                     StorageUnit::GetSize.
  145.         <11>    12/16/93    CC        Added methods to create, write, and read
  146.                                     Edition files.  Save Edition Manager
  147.                                     section records and aliases persistently.
  148.         <10>    12/14/93    TÇ        InitLink changes.  Internalize, Initialize
  149.                                     went away.
  150.          <9>     12/8/93    CC        ODValueLink -> ODPartListLink to avoid
  151.                                     name conflict.  Removed multiple
  152.                                     constructors.  Added InitPartListLink
  153.          <8>    11/18/93    TÇ        call inherited::InitializePersistent()
  154.                                     ::Externalize()
  155.          <7>    11/17/93    CC        RegisterDependent calls the LinkUpdated
  156.                                     method of its part argument.
  157.          <6>     9/29/93    VL        Added InitializePersistent.
  158.          <5>      7/1/93    NP        Abstract/Concrete breakout.
  159.          <4>     6/10/93    NP        Added comments.
  160.          <3>     4/28/93    NP        File name changes.
  161.          <2>     4/27/93    NP        Now compilable.
  162.          <1>     4/21/93    NP        first checked in
  163.  
  164.     To Do:
  165.     In Progress:
  166. */
  167.  
  168. #define VARIABLE_MACROS
  169.  
  170. #define ODLinkSource_Class_Source
  171. #include <LinkSrc.xih>
  172.  
  173. #ifndef SOM_ODLink_xh
  174. #include <Link.xh>
  175. #endif
  176.  
  177. #ifndef _EXCEPT_
  178. #include <Except.h>
  179. #endif
  180.  
  181. #ifndef _ODMEMORY_
  182. #include <ODMemory.h>
  183. #endif
  184.  
  185. #ifndef _CONSTDEF_
  186. #include <ConstDef.h>
  187. #endif
  188.  
  189. #ifndef SOM_ODLinkManager_xh
  190. #include <LinkMgr.xh>
  191. #endif
  192.  
  193. #ifndef SOM_ODPart_xh
  194. #include <Part.xh>
  195. #endif
  196.  
  197. #ifndef SOM_ODSession_xh
  198. #include <ODSessn.xh>
  199. #endif
  200.  
  201. #ifndef SOM_ODContainer_xh
  202. #include <ODCtr.xh>
  203. #endif
  204.  
  205. #ifndef SOM_ODDocument_xh
  206. #include <Document.xh>
  207. #endif
  208.  
  209. #ifndef SOM_ODDraft_xh
  210. #include <Draft.xh>
  211. #endif
  212.  
  213. #ifndef SOM_ODStorageSystem_xh
  214. #include <ODStor.xh>
  215. #endif
  216.  
  217. #ifndef _PLFMFILE_
  218. #include <PlfmFile.h>
  219. #endif
  220.  
  221. #ifndef SOM_ODStorageUnit_xh
  222. #include <StorageU.xh>
  223. #endif
  224.  
  225. #ifndef SOM_Module_OpenDoc_StdProps_defined
  226. #include <StdProps.xh>
  227. #endif
  228.  
  229. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  230. #include <StdTypes.xh>
  231. #endif
  232.  
  233. #ifndef _ISOSTR_
  234. #include <ISOStr.h>
  235. #endif
  236.  
  237. #ifndef __ERRORS__
  238. #include <Errors.h>
  239. #endif
  240.  
  241. #ifndef _ODUTILS_
  242. #include <ODUtils.h>
  243. #endif
  244.  
  245. #ifndef _DOCUTILS_
  246. #include <DocUtils.h>
  247. #endif
  248.  
  249. #ifndef _ODDEBUG_
  250. #include <ODDebug.h>
  251. #endif
  252.  
  253. #ifndef _BARRAY_
  254. #include <BArray.h>
  255. #endif
  256.  
  257. #ifndef _STDTYPIO_
  258. #include <StdTypIO.h>
  259. #endif
  260.  
  261. #ifndef _STORUTIL_
  262. #include <StorUtil.h>
  263. #endif
  264.  
  265. #ifndef _TEMPOBJ_
  266. #include "TempObj.h"
  267. #endif
  268.  
  269. #pragma segment ODLinkSource
  270.  
  271. //==============================================================================
  272. // ODLinkSource
  273. //==============================================================================
  274.  
  275. //------------------------------------------------------------------------------
  276. // ODLinkSource: somUninit
  277. //------------------------------------------------------------------------------
  278.  
  279. SOM_Scope void  SOMLINK ODLinkSourcesomUninit(ODLinkSource *somSelf)
  280. {
  281.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  282.     ODLinkSourceMethodDebug("ODLinkSource","somUninit");
  283.  
  284.     parent_somUninit(somSelf);
  285. }
  286.  
  287. //------------------------------------------------------------------------------
  288. // ODLinkSource: InitLinkSource
  289. //------------------------------------------------------------------------------
  290.  
  291. SOM_Scope void  SOMLINK ODLinkSourceInitLinkSource(ODLinkSource *somSelf, Environment *ev,
  292.         ODStorageUnit* storageUnit,
  293.         ODPart* sourcePart)
  294. {
  295.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  296.     ODLinkSourceMethodDebug("ODLinkSource","InitLinkSource");
  297.  
  298.     SOM_CATCH return;
  299.  
  300.     /* Moved from somInit. SOM itself sets fields to zero
  301.     _fSection = (SectionHandle) kODNULL;
  302.     _fStatus = 0;
  303.     _fDirty = kODFalse;
  304.     */
  305.     somSelf->InitBaseLinkSource(ev, storageUnit, sourcePart);
  306.  
  307.     somSelf->SetLinkSourceDirty(ev);
  308. }
  309.  
  310. //------------------------------------------------------------------------------
  311. // ODLinkSource: InitLinkSourceFromStorage
  312. //------------------------------------------------------------------------------
  313.  
  314. SOM_Scope void  SOMLINK ODLinkSourceInitLinkSourceFromStorage(ODLinkSource *somSelf, Environment *ev,
  315.         ODStorageUnit* storageUnit)
  316. {
  317.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  318.     ODLinkSourceMethodDebug("ODLinkSource","InitLinkSourceFromStorage");
  319.  
  320.     SOM_CATCH return;
  321.  
  322.     /* Moved from somInit. SOM itself sets fields to zero
  323.     _fSection = (SectionHandle) kODNULL;
  324.     _fStatus = 0;
  325.     _fDirty = kODFalse;
  326.     */
  327.     somSelf->InitBaseLinkSourceFromStorage(ev, storageUnit);
  328.  
  329.     if (ODSUExistsThenFocus(ev, storageUnit, kODPropLinkSection, kODApplesect) )
  330.     {
  331.         const int sectionRecordSize = sizeof(SectionRecord);
  332.  
  333.         ODValue value;
  334.  
  335.         if ( storageUnit->GetSize(ev) != sectionRecordSize )
  336.             THROW(kODErrCorruptLinkSource);
  337.  
  338.         _fSection = (SectionHandle) ODNewHandle(sectionRecordSize);
  339.         value = ODLockHandle((ODHandle) _fSection);
  340.         StorageUnitGetValue(storageUnit, ev, sectionRecordSize, value);
  341.         ODUnlockHandle((ODHandle) _fSection);
  342.         
  343.         if ( (**_fSection).kind != stSubscriber )
  344.         {
  345.             ODDisposeHandle((ODHandle) _fSection);
  346.             _fSection = (SectionHandle) kODNULL;
  347.             THROW(kODErrCorruptLinkSource);
  348.         }
  349.     
  350.         storageUnit->Focus(ev, kODPropEditionAlias, kODPosUndefined, kODApplealis, (ODValueIndex)0, kODPosUndefined);
  351.         ODULong size = storageUnit->GetSize(ev);
  352.  
  353.         if ( size < sizeof(AliasRecord) )
  354.         {
  355.             ODDisposeHandle((ODHandle) _fSection);
  356.             _fSection = (SectionHandle) kODNULL;
  357.             THROW(kODErrCorruptLinkSource);
  358.         }
  359.  
  360.         AliasHandle alias = (AliasHandle) ODNewHandle(size);
  361.         value = ODLockHandle((ODHandle) alias);
  362.         StorageUnitGetValue(storageUnit, ev, size, value);
  363.         ODUnlockHandle((ODHandle) alias);
  364.  
  365.         (**_fSection).alias = alias;
  366.         (**_fSection).refCon = (long) somSelf;
  367.  
  368.         ODDraftPermissions permissions = storageUnit->GetDraft(ev)->GetPermissions(ev);
  369.  
  370.         if (HAS_WRITE_ACCESS(permissions))
  371.         {
  372.             ODBoolean aliasWasUpdated;
  373.  
  374.             ODContainer* container = storageUnit->GetDraft(ev)->GetDocument(ev)->GetContainer(ev);
  375.             ODFileSpec documentSpec = GetODFileSpecFromContainer(ev, container);
  376.  
  377.             _fStatus = RegisterSection(&documentSpec, _fSection, &aliasWasUpdated);
  378.             
  379.             // Remember any error returned by RegisterSection.  The most likely errors are:
  380.             //    multiplePublisherWrn = -460,        A Publisher is already registered for that container
  381.             //    containerNotFoundWrn = -461,        Could not find editionContainer at this time
  382.             //    containerAlreadyOpenWrn = -462,        Container already opened by this section
  383.             //    notThePublisherWrn = -463,            Not the first registered publisher for that container
  384.  
  385.             if ( _fStatus == containerNotFoundWrn )
  386.                 _fStatus = kODErrCannotFindLinkSourceEdition;
  387.  
  388.             somSelf->Acquire(ev);    // Link must not be deleted untill its section is unregistered!
  389.         }
  390.     }
  391. }
  392.  
  393. //------------------------------------------------------------------------------
  394. // ODLinkSource: Release (OVERRIDE)
  395. //------------------------------------------------------------------------------
  396.  
  397. SOM_Scope void  SOMLINK ODLinkSourceRelease(ODLinkSource *somSelf, Environment *ev)
  398. {
  399.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  400.     ODLinkSourceMethodDebug("ODLinkSource","Release");
  401.  
  402.     SOM_CATCH return;
  403.  
  404.     parent_Release(somSelf, ev);
  405.  
  406. #if ODDebug
  407.     somPrintf("ODLinkSource %d::Release: Ref count is %d\n", somSelf->GetID(ev), somSelf->GetRefCount(ev));
  408. #endif
  409.  
  410.     if ( somSelf->GetRefCount(ev) == 0 )
  411.         somSelf->GetStorageUnit(ev)->GetDraft(ev)->ReleaseLinkSource(ev, somSelf);
  412. }
  413.  
  414. //------------------------------------------------------------------------------
  415. // ODLinkSource: Externalize (OVERRIDE)
  416. //------------------------------------------------------------------------------
  417.  
  418. SOM_Scope void  SOMLINK ODLinkSourceExternalize(ODLinkSource *somSelf, Environment *ev)
  419. {
  420.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  421.     ODLinkSourceMethodDebug("ODLinkSource","Externalize");
  422.  
  423.     SOM_CATCH return;
  424.  
  425.     parent_Externalize(somSelf,ev);
  426.  
  427.     if ( _fDirty )
  428.     {
  429.         ODStorageUnit* su = somSelf->GetStorageUnit(ev);
  430.     
  431.         if ( _fSection == (SectionHandle) kODNULL )
  432.         {
  433.             ODSURemoveProperty(ev, su, kODPropLinkSection);
  434.             ODSURemoveProperty(ev, su, kODPropEditionAlias);
  435.         }
  436.         else
  437.         {
  438.             SectionPtr theSectionPtr = (SectionPtr) ODLockHandle((ODHandle) _fSection);
  439.     
  440.             ODSUForceFocus(ev, su, kODPropLinkSection, kODApplesect);
  441.             StorageUnitSetValue(su, ev, ODGetHandleSize((ODHandle) _fSection), (ODValue) theSectionPtr);
  442.             
  443.             ODValue theAliasPtr = ODLockHandle((ODHandle) theSectionPtr->alias);
  444.             ODSUForceFocus(ev, su, kODPropEditionAlias, kODApplealis);
  445.             StorageUnitSetValue(su, ev, ODGetHandleSize((ODHandle) theSectionPtr->alias), theAliasPtr);
  446.             
  447.             ODUnlockHandle((ODHandle) theSectionPtr->alias);
  448.             ODUnlockHandle((ODHandle) _fSection);
  449.         }
  450.         _fDirty = kODFalse;
  451.     }
  452. }
  453.  
  454. //------------------------------------------------------------------------------
  455. // ODLinkSource: CloneInto (OVERRIDE)
  456. //------------------------------------------------------------------------------
  457.  
  458. SOM_Scope void  SOMLINK ODLinkSourceCloneInto(ODLinkSource *somSelf, Environment *ev,
  459.         ODDraftKey key,
  460.         ODStorageUnit* toSU,
  461.         ODFrame* scopeFrame)
  462. {
  463.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  464.     ODLinkSourceMethodDebug("ODLinkSource","CloneInto");
  465.  
  466.     SOM_CATCH return;
  467.     
  468.     // If one of our properties already exists, this object has been cloned already
  469.     if ( toSU->Exists(ev, kODPropLinkSection, kODApplesect, 0) )
  470.         return;
  471.  
  472.     parent_CloneInto(somSelf, ev, key, toSU, scopeFrame);
  473.  
  474.     if ( _fSection != (SectionHandle) kODNULL )
  475.     {
  476.         ODSUForceFocus(ev, toSU, kODPropLinkSection, kODApplesect);
  477.         StorageUnitSetValue(toSU, ev, ODGetHandleSize((ODHandle) _fSection), (ODValue) *_fSection);
  478.         
  479.         ODSUForceFocus(ev, toSU, kODPropEditionAlias, kODApplealis);
  480.         StorageUnitSetValue(toSU, ev, ODGetHandleSize((ODHandle) (**_fSection).alias), (ODValue) *((**_fSection).alias));
  481.     }
  482. }
  483.  
  484. //------------------------------------------------------------------------------
  485. // ODLinkSource: ReleaseAll (OVERRIDE)
  486. //------------------------------------------------------------------------------
  487.  
  488. SOM_Scope void  SOMLINK ODLinkSourceReleaseAll(ODLinkSource *somSelf, Environment *ev)
  489. {
  490.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  491.     ODLinkSourceMethodDebug("ODLinkSource","ReleaseAll");
  492.  
  493.     SOM_CATCH return;
  494.  
  495.     parent_ReleaseAll(somSelf,ev);
  496.  
  497.     if ( _fSection != (SectionHandle) kODNULL )
  498.     {
  499.         ODDraftPermissions permissions = somSelf->GetStorageUnit(ev)->GetDraft(ev)->GetPermissions(ev);
  500.  
  501.         if (HAS_WRITE_ACCESS(permissions))
  502.         {
  503.             OSErr error = UnRegisterSection(_fSection);
  504.             somSelf->Release(ev);    // RefCount incremented when section was registered
  505.         }
  506.  
  507.         ODDisposeHandle((ODHandle) (**_fSection).alias);
  508.         ODDisposeHandle((ODHandle) _fSection);
  509.         _fSection = (SectionHandle) kODNULL;
  510.     }
  511. }
  512.  
  513. //------------------------------------------------------------------------------
  514. // ODLinkSource: SetAutoUpdate (OVERRIDE)
  515. //------------------------------------------------------------------------------
  516.  
  517. SOM_Scope void  SOMLINK ODLinkSourceSetAutoUpdate(ODLinkSource *somSelf, Environment *ev,
  518.         ODBoolean automatic)
  519. {
  520.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  521.     ODLinkSourceMethodDebug("ODLinkSource","SetAutoUpdate");
  522.  
  523.     SOM_CATCH return;
  524.  
  525.     parent_SetAutoUpdate(somSelf, ev, automatic);
  526.  
  527.     if ( automatic == kODFalse )
  528.     {
  529.         ODLinkManager* linkManager = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetLinkManager(ev);
  530.         ODLink* link = kODNULL;
  531.         
  532.         TRY
  533.             link = somSelf->GetLink(ev);
  534.         CATCH_ALL
  535.         ENDTRY
  536.  
  537.         if ( link && linkManager->ExportOnSave(ev, link, kODFalse) )
  538.         {
  539.             // The link source was changed from automatic to manual updating,
  540.             // and the last change was waiting for a save to update the edition file.
  541.             // Update the edition file now, so cross-document destinations are
  542.             // consistent with destinations in the same document.  The user will not
  543.             // be able to manually update the link until another change is made
  544.             // to the source of the link.
  545.             ODLinkKey key;
  546.             if ( link->Lock(ev,0,&key) ) 
  547.             {
  548.                 TRY
  549.                     link->UpdateLinkEdition(ev, key);
  550.                 CATCH_ALL
  551.                 ENDTRY
  552.                 link->Unlock(ev, key);
  553.             }
  554.         }
  555.     }
  556. }
  557.  
  558. //------------------------------------------------------------------------------
  559. // ODLinkSource: ShowSourceContent (OVERRIDE)
  560. //------------------------------------------------------------------------------
  561.  
  562. SOM_Scope void  SOMLINK ODLinkSourceShowSourceContent(ODLinkSource *somSelf, Environment *ev)
  563. {
  564.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  565.     ODLinkSourceMethodDebug("ODLinkSource","ShowSourceContent");
  566.  
  567.     SOM_CATCH
  568.     {
  569. #if ODDebug
  570.         somPrintf("ODLinkSource %d: ShowSourceContent :Error %d caught\n", somSelf->GetID(ev), ErrorCode());
  571. #endif
  572.         return;
  573.     }
  574.  
  575.     if ( _fSection != (SectionHandle) kODNULL )
  576.     {
  577.         EditionInfoRecord infoRec;
  578.         OSErr error;
  579.  
  580.         if ( IsRegisteredSection(_fSection) == notRegisteredSectionErr ) 
  581.         {
  582.             // Temporarily register to get Editon info
  583.             // $$$$$ This may cause an section Apple event to arrive
  584.             ODBoolean aliasWasUpdated;
  585.             ODContainer* container = somSelf->GetStorageUnit(ev)->GetDraft(ev)->GetDocument(ev)->GetContainer(ev);
  586.             ODFileSpec documentSpec = GetODFileSpecFromContainer(ev, container);
  587.             RegisterSection(&documentSpec, _fSection, &aliasWasUpdated);
  588.             error = GetEditionInfo(_fSection, &infoRec);
  589.             UnRegisterSection(_fSection);
  590.         }
  591.         else
  592.         {
  593.             error = GetEditionInfo(_fSection, &infoRec);
  594.         }
  595.         if ( error != noErr )
  596.             THROW(kODErrCannotFindLinkSource);
  597.         
  598.         error = GoToPublisherSection(&infoRec.container);
  599.         if ( error == fnfErr )
  600.             THROW(kODErrCannotFindLinkSourceEdition);
  601.         else if ( error != noErr )
  602.             THROW(kODErrCannotFindLinkSource);
  603.     }
  604.     else
  605.     {
  606.         parent_ShowSourceContent(somSelf, ev);
  607.     }
  608. }
  609.  
  610. //------------------------------------------------------------------------------
  611. // ODLinkSource: SetSourcePart (OVERRIDE)
  612. //------------------------------------------------------------------------------
  613.  
  614. SOM_Scope void  SOMLINK ODLinkSourceSetSourcePart(ODLinkSource *somSelf, Environment *ev,
  615.         ODStorageUnit* sourcePartSU)
  616. {
  617.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  618.     ODLinkSourceMethodDebug("ODLinkSource","SetSourcePart");
  619.  
  620.     SOM_CATCH return;
  621.  
  622.     ODLinkManager* linkManager = somSelf->GetStorageUnit(ev)->GetSession(ev)->GetLinkManager(ev);
  623.  
  624.     // If there is no source part for this link, delete the edition file when the
  625.     // draft is saved; is there is a source part, make sure the edition file
  626.     // is still maintained.
  627.     linkManager->DeleteOnSave(ev, somSelf->GetLink(ev), (sourcePartSU == kODNULL));
  628.  
  629.     parent_SetSourcePart(somSelf, ev, sourcePartSU);
  630. }
  631.  
  632. //------------------------------------------------------------------------------
  633. // ODLinkSource: SetLinkSourceDirty
  634. //------------------------------------------------------------------------------
  635.  
  636. SOM_Scope void  SOMLINK ODLinkSourceSetLinkSourceDirty(ODLinkSource *somSelf, Environment *ev)
  637. {
  638.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  639.     ODLinkSourceMethodDebug("ODLinkSource","SetLinkSourceDirty");
  640.  
  641.     SOM_TRY    
  642.         _fDirty = kODTrue;
  643.  
  644.         ODDraft* draft = somSelf->GetStorageUnit(ev)->GetDraft(ev);
  645.         if ( draft->GetPermissions(ev) != kODDPReadOnly )
  646.             draft->SetChangedFromPrev(ev);
  647.     SOM_CATCH_ALL
  648.     SOM_ENDTRY
  649. }
  650.  
  651. //------------------------------------------------------------------------------
  652. // ODLinkSource: UseLinkEdition
  653. //------------------------------------------------------------------------------
  654.  
  655. SOM_Scope void  SOMLINK ODLinkSourceUseLinkEdition(ODLinkSource *somSelf, Environment *ev,
  656.         EditionContainerSpec editionContainer,
  657.         ODFileSpec* documentSpec,
  658.         ODULong sectionID,
  659.         ODLinkKey key)
  660. {
  661.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  662.     ODLinkSourceMethodDebug("ODLinkSource","UseLinkEdition");
  663.  
  664.     SOM_CATCH return;
  665.  
  666.     somSelf->KeyValid(ev, key);
  667.  
  668.     if ( _fSection != (SectionHandle) kODNULL )
  669.         THROW(kODErrAlreadyImportedLink);
  670.  
  671.     OSErr error = NewSection(&editionContainer, documentSpec, stSubscriber, sectionID, sumAutomatic, &_fSection);
  672.     THROW_IF_ERROR(error);
  673.  
  674.     (**_fSection).refCon = (long) somSelf;
  675.     somSelf->Acquire(ev);    // Link must not be deleted untill its section is unregistered!
  676.  
  677.     somSelf->SetLinkSourceDirty(ev);
  678. }
  679.  
  680. //------------------------------------------------------------------------------
  681. // ODLinkSource: ReadLinkEdition
  682. //------------------------------------------------------------------------------
  683.  
  684. SOM_Scope void  SOMLINK ODLinkSourceReadLinkEdition(ODLinkSource *somSelf, Environment *ev,
  685.         ODLinkKey key)
  686. {
  687.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  688.     ODLinkSourceMethodDebug("ODLinkSource","ReadLinkEdition");
  689.  
  690.     SOM_CATCH return;
  691.  
  692.     somSelf->KeyValid(ev, key);
  693.  
  694.     OSErr            openError;
  695.     OSErr            readError = noErr;
  696.     OSErr            closeError;
  697.     EditionRefNum    edRefNum;
  698.     ODHandle        dataHandle = kODNULL;        ODVolatile(dataHandle);
  699.     long            dataSize;
  700.     ODBoolean        successful = kODFalse;
  701.  
  702.     if ( _fSection == (SectionHandle) kODNULL )
  703.         THROW(kODErrNotImportedLink);
  704.  
  705.     openError = OpenEdition(_fSection, &edRefNum);
  706.     if ( openError )
  707.     {
  708.         _fStatus = openError;
  709.         THROW(openError);
  710.     }
  711.     else if ( _fStatus == kODErrCannotFindLinkSourceEdition )
  712.     {
  713.         _fStatus = 0;
  714.     }
  715.  
  716.     readError = EditionHasFormat(edRefNum, kODScrapTypeODBentoContainer, &dataSize);
  717.     if ( readError )
  718.         _fStatus = readError;
  719.     if ( (readError == noErr) && (dataSize > 0) )
  720.     {
  721.         TRY
  722.             dataHandle = ODNewHandle(dataSize);
  723.             void* dataPtr = ODLockHandle(dataHandle);
  724.             readError = ReadEdition (edRefNum, kODScrapTypeODBentoContainer, dataPtr, &dataSize);
  725.             ODUnlockHandle(dataHandle);
  726.             THROW_IF_ERROR(readError);
  727.  
  728.             // Changes originating in another document get a fresh change ID, since
  729.             // OpenDoc is not concerned with cycles across documents.
  730.             // Note that the source document does not mark the edition file with a change ID
  731.             // (one could be kept in the draft properties, I suppose).
  732.             ODUpdateID updateID = somSelf->GetStorageUnit(ev)->GetSession(ev)->UniqueUpdateID(ev);
  733.             somSelf->Clear(ev, updateID, key);
  734.             ODStorageUnit* contentSU = somSelf->GetContentStorageUnit(ev, key);
  735.             
  736.             // Existing properties inhibit cloning in the same property, so remove all properties
  737.             // from the content storage unit before cloning.
  738.             contentSU->Focus(ev, (ODPropertyName) kODNULL, kODPosAll, kODTypeAll, 0, kODPosUndefined);
  739.             ODULong numProperties = contentSU->CountProperties(ev);
  740.             ODULong i;
  741.             for (i = 1; i <= numProperties; i++) {
  742.                 contentSU->Focus(ev, (ODPropertyName) kODNULL, kODPosNextSib, kODTypeAll, 0, kODPosUndefined);
  743.                 contentSU->Remove(ev);
  744.                 }
  745.             
  746.             somSelf->CloneFromMemoryContainer(ev, contentSU, dataHandle);
  747.  
  748.             successful = kODTrue;
  749.  
  750.             ODDisposeHandle(dataHandle);
  751.         CATCH_ALL
  752.             _fStatus = ErrorCode();
  753.             ODDisposeHandle(dataHandle);
  754.             WARN("Throw from ReadEditionFile");
  755.         ENDTRY
  756.     }
  757.  
  758.     closeError = CloseEdition(edRefNum, successful);
  759.     if ( successful )
  760.         somSelf->SetChangeTime(ev, (**_fSection).mdDate, key);
  761.  
  762.     THROW_IF_ERROR(readError);
  763. }
  764.  
  765. //------------------------------------------------------------------------------
  766. // ODLinkSource: SetStatus
  767. //------------------------------------------------------------------------------
  768.  
  769. SOM_Scope void  SOMLINK ODLinkSourceSetStatus(ODLinkSource *somSelf, Environment *ev,
  770.         ODError error)
  771. {
  772.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  773.     ODLinkSourceMethodDebug("ODLinkSource","SetStatus");
  774.  
  775.     _fStatus = error;
  776. }
  777.  
  778. //------------------------------------------------------------------------------
  779. // ODLinkSource: GetStatus
  780. //------------------------------------------------------------------------------
  781.  
  782. SOM_Scope ODError  SOMLINK ODLinkSourceGetStatus(ODLinkSource *somSelf, Environment *ev)
  783. {
  784.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  785.     ODLinkSourceMethodDebug("ODLinkSource","GetStatus");
  786.  
  787.     return _fStatus;
  788. }
  789.  
  790. //------------------------------------------------------------------------------
  791. // ODLinkSource: CloneFromMemoryContainer
  792. //------------------------------------------------------------------------------
  793. // This method does not call it's draft's SetChangeFromPrev() method so that the
  794. // user is not prompted to save changes if the only change was to update a link
  795. // from an edition file.
  796.  
  797.  
  798. SOM_Scope void  SOMLINK ODLinkSourceCloneFromMemoryContainer(ODLinkSource *somSelf, Environment *ev,
  799.         ODStorageUnit* contentSU,
  800.         ODHandle containerHandle)
  801. {
  802.     ODLinkSourceData *somThis = ODLinkSourceGetData(somSelf);
  803.     ODLinkSourceMethodDebug("ODLinkSource","CloneFromMemoryContainer");
  804.  
  805.     SOM_CATCH return;
  806.  
  807.     ODStorageUnitID        rootID;
  808.     ODDraft*            myDraft = contentSU->GetDraft(ev);
  809.     ODSession*            session = somSelf->GetStorageUnit(ev)->GetSession(ev);
  810.     
  811.     TempODContainer container = GetMemoryContainer(ev, session, containerHandle, kODBentoMemoryContainer);
  812.  
  813.     TempODDocument document = container->AcquireDocument(ev, kODDefaultDocument);
  814.         
  815.     TempODDraft draft = document->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  816.         
  817.     { TempODStorageUnit draftProperties = draft->AcquireDraftProperties(ev);
  818.       rootID = ODGetStrongSURefProp(ev, draftProperties, kODPropRootPartSU, kODStrongStorageUnitRef);
  819.     }
  820.     
  821.     TempODStorageUnit rootSU = draft->AcquireStorageUnit(ev, rootID);
  822.  
  823.     ODDraftKey draftKey = draft->BeginClone(ev, myDraft, kODNULL, kODCloneAll);
  824.     TRY
  825.         draft->Clone(ev, draftKey, rootID, contentSU->GetID(ev), 0);    
  826.  
  827.         if ( ODSUExistsThenFocus(ev, rootSU, kODPropContentFrame, kODWeakStorageUnitRef) )
  828.         {
  829.             ODID contentFrameID = ODGetWeakSURefProp(ev, rootSU, kODPropContentFrame, kODWeakStorageUnitRef);
  830.             draft->Clone(ev, draftKey, contentFrameID, kODNULLID, 0);                
  831.         }        
  832.     CATCH_ALL
  833.         draft->AbortClone(ev, draftKey);
  834.         RERAISE;
  835.     ENDTRY
  836.     draft->EndClone(ev, draftKey);
  837. }
  838.